#include "timeSlice.h"

typedef struct{
    uint32_t status;            //系统状态
    uint32_t isInited;          //是否已经初始化
    uint32_t task_cnt;          //任务数量
    T_task_ts *taskPool;        //任务列表指针
    uint32_t ts_tick;           //系统节拍

    //空闲统计
    uint32_t sec_tick;          //秒节拍计数
    uint32_t idle_tick_per_sec; //每秒空闲节拍数
    float    idle_percnet;      //空闲时间占比

}T_ts_manage;                   //时间片系统管理

static T_ts_manage s_ts_manage = {TS_INIT,0,0,0,0,0,0};

/*============================================================================
 任务初始化
 pTaskPool:任务池指针
 task_cnt:任务数量
 ============================================================================*/
void api_ts_task_init(T_task_ts *pTaskPool,uint32_t task_cnt)
{
    int i;

    s_ts_manage.task_cnt = task_cnt;
    s_ts_manage.taskPool = pTaskPool;

    for(i = 0;i < task_cnt; i++)
    {
        pTaskPool[i].exec_period = TS_MS2TICK(pTaskPool[i].exec_period_ms);//配置时填充毫秒 此处转换为tick数
        pTaskPool[i].status =  TS_TASK_CNTDOWN;
        pTaskPool[i].sleep_cntDown = 0;
        pTaskPool[i].exec_cntDown = pTaskPool[i].exec_period;
        pTaskPool[i].exec_total_time = 0;
        pTaskPool[i].exec_count = 0;
        pTaskPool[i].exec_max_time = 0;
        pTaskPool[i].exec_min_time = 0xffffffff;
    }

    s_ts_manage.status = TS_STOP;
}

/*============================================================================
 时间片调度开启
 ============================================================================*/
void api_ts_start()
{
    s_ts_manage.status = TS_RUN;
}

/*============================================================================
 时间片调度关闭
 ============================================================================*/
void api_ts_stop()
{
    s_ts_manage.status = TS_STOP;
}

/*============================================================================
 返回任务数
 ============================================================================*/
uint32_t api_ts_get_task_cnt()
{
    return s_ts_manage.task_cnt;
}

/*============================================================================
 返回时间片系统状态
 ============================================================================*/
uint32_t api_ts_get_ts_status()
{
    return s_ts_manage.status;
}

/*============================================================================
 任务开始
 task_id:任务id
 ============================================================================*/
void api_ts_task_start(uint32_t task_id)
{
    int i;
    for( i = 0;i < s_ts_manage.task_cnt; i++)
    {
        if(s_ts_manage.taskPool[i].id == task_id)
        {
            s_ts_manage.taskPool[i].status = TS_TASK_CNTDOWN;
            s_ts_manage.taskPool[i].exec_cntDown = s_ts_manage.taskPool[i].exec_period;

            break;
        }
    }
}

/*============================================================================
 任务暂停
 task_id:任务id
 ============================================================================*/
void api_ts_task_stop(uint32_t task_id)
{
    int i;
    for( i = 0;i < s_ts_manage.task_cnt; i++)
    {
        if(s_ts_manage.taskPool[i].id == task_id)
        {
            s_ts_manage.taskPool[i].status = TS_TASK_STOP;
            s_ts_manage.taskPool[i].exec_cntDown = s_ts_manage.taskPool[i].exec_period;
            break;
        }
    }
}

/*============================================================================
 任务休眠
 task_id:任务id
 ms:欲休眠毫秒数
 ============================================================================*/
void api_ts_task_sleep(uint32_t task_id,uint32_t ms)
{
    int i;
    for( i = 0;i < s_ts_manage.task_cnt; i++)
    {
        if(s_ts_manage.taskPool[i].id == task_id)
        {
            s_ts_manage.taskPool[i].status = TS_TASK_SLEEP;
            s_ts_manage.taskPool[i].sleep_cntDown = TS_MS2TICK(ms);
            break;
        }
    }
}


void __weak hook_ts_idle_task()
{
    
}

/*============================================================================
 时间片调度器
 在定时器中断中执行调度
 ============================================================================*/
void api_ts_task_schedule()
{
  
    uint32_t i;
    uint32_t flag_idle = 1;
    
    if(s_ts_manage.taskPool == 0 || s_ts_manage.status == TS_STOP)
    {
        return;
    }

    s_ts_manage.ts_tick++;

    for( i = 0;i < s_ts_manage.task_cnt; i++)
    {
        switch(s_ts_manage.taskPool[i].status)
        {
            case TS_TASK_STOP:
                break;
            case TS_TASK_RUN:
                flag_idle = 0;
                if(s_ts_manage.taskPool[i].exec_cntDown != 0)
                {
                    s_ts_manage.taskPool[i].exec_cntDown--;
                }
                break;
            case TS_TASK_READY:
                if(s_ts_manage.taskPool[i].exec_cntDown != 0)
                {
                    s_ts_manage.taskPool[i].exec_cntDown--;
                }
                s_ts_manage.taskPool[i].exec_ready_wait_tick++;
                break;
            case TS_TASK_CNTDOWN:
                if(s_ts_manage.taskPool[i].exec_cntDown != 0)
                {
                    s_ts_manage.taskPool[i].exec_cntDown--;
                }
                if(s_ts_manage.taskPool[i].exec_cntDown == 0)
                {
                    //重置
                    s_ts_manage.taskPool[i].exec_cntDown = s_ts_manage.taskPool[i].exec_period;
                    //置就绪态
                    s_ts_manage.taskPool[i].status = TS_TASK_READY;
                }
                break;
            case TS_TASK_SLEEP:
                s_ts_manage.taskPool[i].sleep_cntDown--;
                if(s_ts_manage.taskPool[i].sleep_cntDown == 0)
                {
                    //睡眠结束
                    s_ts_manage.taskPool[i].status = TS_TASK_CNTDOWN;
                }
                break;
            default:
                break;
        }
    }

    //空闲状态
    if(flag_idle == 1)
    {
        s_ts_manage.idle_tick_per_sec++;
    }
    //每秒统计空闲占比
    if(++s_ts_manage.sec_tick >= 1000 / TICK_PERIOD_MS)
    {
        s_ts_manage.idle_percnet = 100.0 * s_ts_manage.idle_tick_per_sec / s_ts_manage.sec_tick;
        s_ts_manage.idle_tick_per_sec = 0;
        s_ts_manage.sec_tick = 0;
    }
}



/*============================================================================
 任务执行
 task_index:任务标号
 ============================================================================*/
static void s_ts_exec(uint32_t task_index)
{
    uint32_t tick_start = 0;
    uint32_t tick_end = 0;
    uint32_t tick_exec = 0;

    //置运行状态
    s_ts_manage.taskPool[task_index].status = TS_TASK_RUN;
    //清ready等待时间
    s_ts_manage.taskPool[task_index].exec_ready_wait_tick = 0;
    //执行
    tick_start = s_ts_manage.ts_tick;
    s_ts_manage.taskPool[task_index].handle();
    s_ts_manage.taskPool[task_index].exec_count++;
    tick_end = s_ts_manage.ts_tick;
    tick_exec = TS_TICK2MS(tick_end - tick_start);
    s_ts_manage.taskPool[task_index].exec_total_time += tick_exec;
    //置倒计时 但要保证执行过程中没有改变状态 应为任务中有可能进行任务休眠等操作
    if(s_ts_manage.taskPool[task_index].status == TS_TASK_RUN)
    {
        s_ts_manage.taskPool[task_index].status = TS_TASK_CNTDOWN;
    }
    //统计运行时间
    if(tick_exec > s_ts_manage.taskPool[task_index].exec_max_time)
    {
        s_ts_manage.taskPool[task_index].exec_max_time = tick_exec;
    }
    else if(tick_exec < s_ts_manage.taskPool[task_index].exec_min_time)
    {
        s_ts_manage.taskPool[task_index].exec_min_time = tick_exec; 
    }
}

/*============================================================================
 根据调度结果运行相应任务
 ============================================================================*/
void api_ts_task_exec()
{
    uint32_t exec_task_index,i;
    uint32_t prority_temp;
    uint32_t exec_flag = 0;

    if(s_ts_manage.taskPool == 0)
    {
        return;
    }

    while(1)
    {
        exec_flag = 0;
        exec_task_index = 0;
        prority_temp = 0xffffffff;

        //找出就绪态中的最高优先级的任务索引
        for( i = 0;i < s_ts_manage.task_cnt; i++)
        {
            if(s_ts_manage.taskPool[i].status == TS_TASK_READY)
            {
                exec_flag = 1;
                if(prority_temp > s_ts_manage.taskPool[i].prority)
                {
                    prority_temp = s_ts_manage.taskPool[i].prority;
                    exec_task_index = i;
                }
            }
        }

        if(exec_flag == 1)
        {
            s_ts_exec(exec_task_index);
        }

        //运行空闲任务
        hook_ts_idle_task();

        //异常恢复 检查就绪态持续2倍的exec_period却仍然未运行的任务
        //可能原因：高优先级的任务运行时间过长，超过了任务的运行周期 ,导致调度塞住,使得低优先级任务无法运行
        //异常恢复旨在READY后的任务必定得到执行
        for( i = 0;i < s_ts_manage.task_cnt; i++)
        {
            if(s_ts_manage.taskPool[i].exec_ready_wait_tick > 2*s_ts_manage.taskPool[i].exec_period)
            {
                exec_flag = 1;
                s_ts_exec(i);
            }
        }
        
    }

    
}

/*============================================================================
 返回任务状态
 task_id:任务id
 ============================================================================*/
uint32_t api_ts_task_get_status(uint32_t task_id)
{
    int i;
    uint32_t res;
    for( i = 0;i < s_ts_manage.task_cnt; i++)
    {
        if(s_ts_manage.taskPool[i].id == task_id)
        {
            res = s_ts_manage.taskPool[i].status;
            break;
        }
    }

    return res;
}

uint32_t api_ts_getTick()
{
    return s_ts_manage.ts_tick;
}